package com.alex.utils.html.extractor;

import java.io.File;
import java.util.LinkedList;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.text.StrBuilder;

import com.alex.utils.html.HtmlUtils;
import com.alex.utils.html.element.ContainerTag;
import com.alex.utils.html.element.Element;
import com.alex.utils.html.element.Text;
import com.alex.utils.html.parser.HtmlParser;
import com.alex.utils.text.TextUtils;

public class HtmlTextExtractor {

	private FragmentFilter fragmentFilter;
	
	public void setFragmentFilter(FragmentFilter fragmentFilter) {
		this.fragmentFilter = fragmentFilter;
	}
	
	private void extract(String html) {
		ContainerTag root = HtmlParser.parseHtml(html);

		LinkedList<Element> queue = new LinkedList<Element>();
		queue.add(root);
		
		ContainerTag body = null;
		
		@SuppressWarnings("unused")
		String title = null;
		
		while (!queue.isEmpty()) {
			Element element = queue.removeFirst();
			if (element instanceof ContainerTag) {
				ContainerTag tag = (ContainerTag) element;
				if ("title".equals(tag.getName())) {
					for (Element el : tag.getChilds()) {
						if (el instanceof Text) {
							title = ((Text) el).getText();
						}
					}
					continue;
				}
				
				if ("body".equals(tag.getName())) {
					body = tag;
					break;
				}
				queue.addAll(0, tag.getChilds());
			}
		}
		
		queue = new LinkedList<Element>();
		queue.add(body);

		StrBuilder extractedText = new StrBuilder();
		StrBuilder currentFragment = new StrBuilder();
		while (!queue.isEmpty()) {
			Element element = queue.removeFirst();
			if (element instanceof ContainerTag) {
				ContainerTag tag = (ContainerTag) element;
				queue.addAll(0, tag.getChilds());

				if (HtmlUtils.isBlockTag(tag.getName())) {
					appendFragment(currentFragment, extractedText);
					currentFragment = new StrBuilder();
				}
			} else if (element instanceof Text) {
				String text = ((Text) element).getText();
				currentFragment.append(text);
			}
		}
		appendFragment(currentFragment, extractedText);
		
		System.out.println(extractedText.toString());
	}

	private void appendFragment(StrBuilder fragment, StrBuilder extractedText) {
		fragment.trim();
		if (fragment.isEmpty() || (fragmentFilter != null && !fragmentFilter.filter(fragment))) {
			return;
		}
		extractedText.append(fragment).append("\n");
	}

	public static void main(String[] args) throws Exception {
		String html = FileUtils.readFileToString(new File("text/1.html"));
		
		HtmlTextExtractor extractor = new HtmlTextExtractor();
		extractor.setFragmentFilter(new FragmentFilter() {
			@Override
			public boolean filter(StrBuilder fragment) {
				return fragment.length() >= 10 && TextUtils.isEndOfSentence(fragment.rightString(1));
			}
		});
		extractor.extract(html);
	}
}
